﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Dycox.Collections;

namespace Dycox.Workflows
{
    public class StageCollection : OwnedCollection<Stage, Workflow>
    {
        public StageCollection(Workflow workflow)
            : base(workflow)
        {
            _lookup = new Dictionary<string, Stage>();
        }

        Dictionary<string, Stage> _lookup;

        protected override void AttachItem(Stage item)
        {
            if (_lookup.ContainsKey(item.Name))
                throw new ArgumentException("Stage " + item.Name + " already defined.");
            if (item.Usage == StageUsage.Placeholder)
                throw new WorkflowException("Cannot attach placeholder stage.");

            bool isEntrance = item.Usage == StageUsage.Entrance;

            if (isEntrance)
            {
                if (Owner.Entrance != null)
                    throw new WorkflowException("An entrance already exists in current workflow.");
            }

            base.AttachItem(item);

            if (isEntrance)
                Owner.Entrance = item;

            _lookup.Add(item.Name, item);
        }

        protected override void DeattachItem(Stage item)
        {
            base.DeattachItem(item);

            _lookup.Remove(item.Name);
            if (Owner.Entrance == item)
                Owner.Entrance = null;
        }

        public Stage this[string name]
        {
            get
            {
                if (name == null)
                    throw new ArgumentNullException("name");

                Stage stage;

                if (_lookup.TryGetValue(name, out stage))
                    return stage;

                throw new ArgumentException("Stage " + name + " not found in " + Owner.Name);
            }
        }

        public Stage this[WFStep step]
        {
            get
            {
                if (step == null)
                    throw new ArgumentNullException("step");

                return this[step.StageName];
            }
        }

        protected override void SetItemOwner(Stage item, Workflow parent)
        {
            item.Workflow = parent;
        }

        protected override Workflow GetItemOwner(Stage item)
        {
            return item.Workflow;
        }
    }

}
